from research.calcor.pos import original_close
class move_stop_close(original_close):
    def __init__(self, argtype="percent", name="", istick=True, stop_loss="stop_loss",atrkey=""):
        super().__init__(argtype, name, istick, stop_loss=stop_loss,atrkey=atrkey)
    def update_target_price(self,ss,b):
        isupdate=False
        if self.target_price is None:
            self.target_price=ss.signals_data[-1]["price"]
        if ss.pos=="buy":
            if self.istick:
                if self.target_price<b["high"]:
                    self.target_price=b["high"]
                    isupdate=True
            else:
                if self.target_price<b["close"]:
                    self.target_price=b["close"]
                    isupdate=True
        elif ss.pos=="sell":
            if self.istick:
                if self.target_price > b["low"]:
                    self.target_price = b["low"]
                    isupdate = True
            else:
                if self.target_price > b["close"]:
                    self.target_price = b["close"]
                    isupdate = True
        return isupdate

    def onbar_ss(self, ss, b):
        return self.onbar_ss_stop_loss(ss,b)
    def onbar_ss_stop_loss(self, ss, b):
        isupdate=self.update_target_price(ss,b)
        isrun = True
        if isupdate and not self.istick:
            isrun = False
        if isrun:
            if ss.pos=="buy":
                stop_loss = self.target_price+ss.__getattribute__(self.stop_loss)
                return self.posbuy_stop_loss(ss, b, stop_loss)
            elif ss.pos=="sell":
                stop_loss = self.target_price-ss.__getattribute__(self.stop_loss)
                return self.possell_stop_loss(ss, b, stop_loss)
        return False,"","",None,None
    def onbar_bar(self, ss, b):
        return self.onbar_bar_stop_loss(ss,b)
    def onbar_bar_stop_loss(self, ss, b):
        isupdate = self.update_target_price(ss, b)
        isrun = True
        if isupdate and not self.istick:
            isrun = False
        if isrun:
            if ss.pos == "buy":
                stop_loss = self.target_price + b[self.stop_loss]
                return self.posbuy_stop_loss(ss, b, stop_loss)
            elif ss.pos == "sell":
                stop_loss = self.target_price - b[self.stop_loss]
                return self.possell_stop_loss(ss, b, stop_loss)
        return False, "", "",None,None
    def onbar_percent(self, ss, b):
        return self.onbar_percent_stop_loss(ss,b)
    def onbar_percent_stop_loss(self, ss, b):
        isupdate = self.update_target_price(ss, b)
        isrun = True
        if isupdate and not self.istick:
            isrun = False
        if isrun:
            if ss.pos == "buy":
                stop_loss = self.target_price * (1 - self.stop_loss)
                return self.posbuy_stop_loss(ss, b, stop_loss)
            elif ss.pos == "sell":
                stop_loss = self.target_price * (1 + self.stop_loss)
                return self.possell_stop_loss(ss, b, stop_loss)
        return False, "", "",None,None
    def onbar_tick(self, ss, b):
        return self.onbar_tick_stop_loss(ss,b)
    def onbar_tick_stop_loss(self, ss, b):
        isupdate = self.update_target_price(ss, b)
        isrun = True
        if isupdate and not self.istick:
            isrun = False
        if isrun:
            if ss.pos == "buy":
                stop_loss = self.target_price - self.stop_loss
                return self.posbuy_stop_loss(ss, b, stop_loss)
            elif ss.pos == "sell":
                stop_loss = self.target_price + self.stop_loss
                return self.possell_stop_loss(ss, b, stop_loss)
        return False, "", "",None,None
    def onbar_atr(self, ss, b):
        return self.onbar_atr_stop_loss(ss,b)
    def onbar_atr_stop_loss(self, ss, b):
        isupdate = self.update_target_price(ss, b)
        isrun=True
        if isupdate and not self.istick:
            isrun=False
        if isrun:
            atr = b[self.atrkey]
            if atr:
                if ss.pos == "buy":
                    stop_loss = self.target_price - self.stop_loss * atr
                    return self.posbuy_stop_loss(ss, b, stop_loss)
                elif ss.pos == "sell":
                    stop_loss = self.target_price + self.stop_loss * atr
                    return self.possell_stop_loss(ss, b, stop_loss)
        return False, "", "",None,None
class move_stop_close_ss:
    def __init__(self,drawdown="drawdown"):
        self.minmax=None
        self.drawdown=drawdown
        if drawdown:
            self.isdel =False
        else:
            self.isdel=True
    def reset(self):
        self.minmax = None
    def onbar(self,ss,b):
        if ss.pos=="buy":
            if self.minmax:
                if self.minmax <=b["close"]:
                    self.minmax = b["close"]
                else:
                    drawdown=ss.__getattribute__(self.drawdown)
                    t1=self.minmax-drawdown>b["close"]
                    if t1:#平仓
                        order = {"obj": b["obj"], "timekey": b["timekey"], "price": b["close"], "action": "closesell",
                                 "info": "移动止损："+str(self.minmax)+","+str(b["close"])+","+str(drawdown)}
                        ss.signals_data.append(order)
                        ss.pos = None
                        self.reset()
                        return True,"closesell"
            else:
                self.minmax=b["close"]
        elif ss.pos=="sell":
            if self.minmax:
                if self.minmax >= b["close"]:
                    self.minmax = b["close"]
                else:
                    drawdown = ss.__getattribute__(self.drawdown)
                    t1 = self.minmax + drawdown < b["close"]
                    if t1:  # 平仓
                        order = {"obj": b["obj"], "timekey": b["timekey"], "price": b["close"], "action": "closebuy",
                                 "info": "移动止损：" + str(self.minmax) + "," + str(b["close"]) + "," + str(drawdown)}
                        ss.signals_data.append(order)
                        ss.pos = None
                        self.reset()
                        return True, "closebuy"
            else:
                self.minmax = b["close"]
        return False,""
class move_stop_close_byprice:
    def __init__(self,drawdown=None):
        self.minmax=None
        self.drawdown=drawdown
        if drawdown:
            self.isdel =False
        else:
            self.isdel=True
    def reset(self):
        self.minmax = None
        if self.isdel:
            self.drawdown = None
    def set_drawdown(self,drawdown=None):
        self.drawdown = drawdown
    def onbar(self,ss,b):
        if ss.pos=="buy":
            if self.minmax:
                if self.minmax <=b["close"]:
                    self.minmax = b["close"]
                else:
                    t1=self.minmax-self.drawdown>b["close"]
                    if t1:#平仓
                        order = {"obj": b["obj"], "timekey": b["timekey"], "price": b["close"], "action": "closesell",
                                 "info": "移动止损："+str(self.minmax)+","+str(b["close"])+","+str(self.drawdown)}
                        ss.signals_data.append(order)
                        ss.pos = None
                        self.reset()
                        return True,"closesell"
            else:
                self.minmax=b["close"]
        elif ss.pos=="sell":
            if self.minmax:
                if self.minmax >= b["close"]:
                    self.minmax = b["close"]
                else:
                    t1 = self.minmax + self.drawdown < b["close"]
                    if t1:  # 平仓
                        order = {"obj": b["obj"], "timekey": b["timekey"], "price": b["close"], "action": "closebuy",
                                 "info": "移动止损：" + str(self.minmax) + "," + str(b["close"]) + "," + str(self.drawdown)}
                        ss.signals_data.append(order)
                        ss.pos = None
                        self.reset()
                        return True, "closebuy"
            else:
                self.minmax = b["close"]
        return False,""
class move_stop_close_bysignal:
    def __init__(self,key="atr",size=1):
        self.minmax=None
        self.key=key
        self.size=size
    def reset(self):
        self.minmax = None
    def onbar(self,ss,b):
        if ss.pos=="buy":
            if self.minmax:
                if self.minmax <=b["close"]:
                    self.minmax = b["close"]
                else:
                    if b[self.key]:
                        drawdown=b[self.key]*self.size
                        t1=self.minmax-drawdown>b["close"]
                        if t1:#平仓
                            order = {"obj": b["obj"], "timekey": b["timekey"], "price": b["close"], "action": "closesell",
                                     "info": "移动止损："+str(self.minmax)+","+str(b["close"])+","+str(drawdown)}
                            ss.signals_data.append(order)
                            ss.pos = None
                            self.reset()
                            return True,"closesell"
            else:
                self.minmax=b["close"]
        elif ss.pos=="sell":
            if self.minmax:
                if self.minmax >= b["close"]:
                    self.minmax = b["close"]
                else:
                    if b[self.key]:
                        drawdown=b[self.key]*self.size
                        t1 = self.minmax + drawdown < b["close"]
                        if t1:  # 平仓
                            order = {"obj": b["obj"], "timekey": b["timekey"], "price": b["close"], "action": "closebuy",
                                     "info": "移动止损：" + str(self.minmax) + "," + str(b["close"]) + "," + str(drawdown)}
                            ss.signals_data.append(order)
                            ss.pos = None
                            self.reset()
                            return True, "closebuy"
            else:
                self.minmax = b["close"]
        return False,""